﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using MyDemo.Application.Service.Plc;
using SL.NET.Core.Service;
using static MyDemo.Application.Service.Plc.MqttService;
using WCS.Application.Entity.Warehous;
using WCS.Application.Service.Rcs;

namespace WCS.Application
{

    public class ActionBackgroundService : IHostedService
    {
        private readonly IServiceScopeFactory _serviceScopeFactory;
        private readonly MqttService _mqttClientService;
        private readonly SqlSugarRepository<AgvactionsEntity> _agvactionsRepo;
        private readonly DispatchService _dispatchService;
        private readonly SysCacheService _sysCacheService;

        public ActionBackgroundService(IServiceScopeFactory serviceScopeFactory
            , MqttService mqttClientService
            )
        {
            _serviceScopeFactory = serviceScopeFactory;
            _mqttClientService = mqttClientService;

            using var serviceScope = _serviceScopeFactory.CreateScope();
            _agvactionsRepo = serviceScope.ServiceProvider.GetService<SqlSugarRepository<AgvactionsEntity>>();
            _dispatchService = serviceScope.ServiceProvider.GetService<DispatchService>();
            _sysCacheService = serviceScope.ServiceProvider.GetService<SysCacheService>();
        }


        public Task StartAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        /// <summary>
        public override async Task<bool> Process(string message)
        {

            try
            {
                while (true)
                {

                    SerilogHelper.WriteLog("ActionOperationService", "start");
                    try
                    {
                        // 不同的任务分组要开多线程并发执行，逻辑待修改

                        // 查询最后一个任务
                        var lastTaskAction = await _agvactionsRepo.AsQueryable()
                           .OrderBy(a => a.Id)
                           .Where(a => a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
                           .FirstAsync();
                        SerilogHelper.WriteLog("ActionOperationService", "lastTaskAction", JsonHelper.ObjectToJson(lastTaskAction));
                        if (lastTaskAction is not null)
                        {

                            // 如果任务是动作，则下发动作指令给设备
                            if (lastTaskAction.ActionType == AgvActionType.Movement)
                            {


                                //查询反馈信息
                                var lastAction = await _agvactionsRepo.AsQueryable()
                                   .OrderBy(a => a.Id).Where(a => a.ActionType == AgvActionType.Feedback && a.Status != ActionStatusEnum.Completed && a.Status != ActionStatusEnum.Cancelled)
                                   .FirstAsync();
                                //获取当前任务的第一个反馈 
                                var last = await _agvactionsRepo.AsQueryable().OrderBy(a => a.Actionsort).Where(a => a.TaskId == lastAction.TaskId && a.ActionType == AgvActionType.Feedback && a.Status != ActionStatusEnum.Completed && a.AgvTaskid == lastAction.AgvTaskid).FirstAsync();

                                //查询反馈信息对应的动作
                                var lastActions = await _agvactionsRepo.AsQueryable()
                                    .OrderBy(a => a.Id)
                                   .Where(a => a.AgvTaskid == last.AgvTaskid && a.ActionType == AgvActionType.Movement)
                                   .FirstAsync();
                                if (lastAction == null)
                                {
                                    Console.WriteLine("没有找到任何动作记录");
                                    return;
                                }

                                SerilogHelper.WriteLog("ActionOperationService", "lastAction", JsonHelper.ObjectToJson(lastAction));
                                switch (last.Status)
                                {
                                    //待处理
                                    case ActionStatusEnum.Pending:
                                        var ss = await _mqttClientService.PublishMessageAsync(
                                             //任务id
                                             (string)lastActions.TaskId,
                                             //动作任务id
                                             (int)lastActions.AgvTaskid,
                                             //托盘码
                                             lastActions.Palletcode,
                                             //设备编号
                                             lastActions.DeviceId,
                                             //起始点位
                                             lastActions.StartPosition,
                                             //目标点位
                                             lastActions.TargetPosition,
                                             //动作执行层
                                             (int)lastActions.TargetFloor,
                                             //起始目标中间的点
                                             //lastAction.Routepoint,
                                             //动作类型 (int)
                                             GetMqttActionType((ActionTypeEnum)lastActions.ActionGroupType)
                                         );
                                        if (ss)
                                        {
                                            lastActions.Status = ActionStatusEnum.Completed;
                                            await _agvactionsRepo.UpdateAsync(lastActions);

                                        }
                                        //last.Status = ActionStatusEnum.Completed;
                                        //await _agvactionsRepo.UpdateAsync(last);
                                        Console.WriteLine($"已向MQTT发送动作指令: {lastActions.TaskId}");

                                        break;
                                    case ActionStatusEnum.Completed:
                                        // 已成功状态逻辑
                                        break;

                                    case ActionStatusEnum.Failed://失败的情况就会去重新生成新的路径
                                        Console.WriteLine($"发现失败动作: {lastActions.TaskId}，开始处理同组任务");

                                        // 1. 将同组的未完成任务全部标记为已取消
                                        await CancelPendingActionsInSameGroup(lastActions);

                                        // 2. 重新制定该组的动作
                                        await ReplanActionsForGroup(lastActions);
                                        break;

                                    default:
                                        Console.WriteLine($"未知状态: {last.Status}");
                                        break;
                                }

                            }
                            // 如果任务是反馈，则读取设备的状态，判断是否已完成
                            else if (lastTaskAction.ActionType == AgvActionType.Feedback)
                            {
                                var deriveId = lastTaskAction.DeviceId;
                                // 提升机
                                if (lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationup || lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationup)
                                {
                                    deriveId = lastTaskAction.TargetPosition;
                                }

                                var deriveInfo = _sysCacheService.Get<DerivesInfo>(deriveId);

                                SerilogHelper.WriteLog("ActionOperationService", "deriveInfo", JsonHelper.ObjectToJson(deriveInfo));
                                // 如果设备状态为空闲，并且任务号与动作任务ID相同，则认为动作已完成，更新反馈状态

                                // 提升机上货
                                if (lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationup)
                                {
                                    // 判断设备的反馈状态
                                    var deviceResponseCache = _sysCacheService.Get<string>(lastTaskAction.TargetPosition + "Response");
                                    if (deviceResponseCache != null && deviceResponseCache.Contains("已反馈"))
                                    {
                                        lastTaskAction.Status = ActionStatusEnum.Completed;
                                        await _agvactionsRepo.UpdateAsync(lastTaskAction);

                                        // 清除设备任务状态
                                        _sysCacheService.Remove(lastTaskAction.TargetPosition + "Response");
                                    }
                                }
                                // 提升机下货
                                else if (lastTaskAction.ActionGroupType == ActionTypeEnum.HoistOperationdown)
                                {
                                    // 判断设备的反馈状态
                                    var deviceResponseCache = _sysCacheService.Get<string>(lastTaskAction.TargetPosition + "Response");
                                    if (deviceResponseCache != null && deviceResponseCache.Contains("已反馈"))
                                    {
                                        lastTaskAction.Status = ActionStatusEnum.Completed;
                                        await _agvactionsRepo.UpdateAsync(lastTaskAction);

                                        // 清除设备任务状态
                                        _sysCacheService.Remove(lastTaskAction.TargetPosition + "Response");
                                    }
                                }
                                // RGV 举货
                                else if (lastTaskAction.ActionGroupType == ActionTypeEnum.Lifting)
                                {
                                    if (deriveInfo.DeviceStatus == 0 && deriveInfo.TaskId.GetCInt() == lastTaskAction.AgvTaskid && deriveInfo.UpStatus == 2)
                                    {
                                        lastTaskAction.Status = ActionStatusEnum.Completed;
                                        await _agvactionsRepo.UpdateAsync(lastTaskAction);
                                    }
                                }
                                // RGV 放货
                                else if (lastTaskAction.ActionGroupType == ActionTypeEnum.Unloading)
                                {
                                    if (deriveInfo.DeviceStatus == 0 && deriveInfo.TaskId.GetCInt() == lastTaskAction.AgvTaskid && deriveInfo.UpStatus == 1)
                                    {
                                        lastTaskAction.Status = ActionStatusEnum.Completed;
                                        await _agvactionsRepo.UpdateAsync(lastTaskAction);
                                    }
                                }
                                // RGV 移动
                                else
                                {
                                    if (deriveInfo.DeviceStatus == 0 && deriveInfo.TaskId.GetCInt() == lastTaskAction.AgvTaskid && deriveInfo.LocationPoint == lastTaskAction.TargetPosition)
                                    {
                                        lastTaskAction.Status = ActionStatusEnum.Completed;
                                        await _agvactionsRepo.UpdateAsync(lastTaskAction);
                                    }

                                }
                                //// 如果设备状态为异常，取消动作
                                //else if (deriveInfo.DeviceEnable == false)
                                //{
                                //    lastTaskAction.Status = ActionStatusEnum.Completed;
                                //    await _agvactionsRepo.UpdateAsync(lastTaskAction);
                                //}
                            }
                        }

                    }
                    catch (Exception ex)
                    {
                        SerilogHelper.WriteErrorLog("ActionOperationService", ex);
                    }
                }

                SerilogHelper.WriteLog("ActionOperationService", "end");

            }
            catch (Exception ex)
            {
                SerilogHelper.WriteErrorLog("ActionBackgroundService_Error", ex);
            }
            return true;
        }

    
    }
}
